/**
 * Created by IntelliJ IDEA.
 * User: Tomek
 * Date: 19.06.12
 * Time: 19:48
 * To change this template use File | Settings | File Templates.
 */
package {
import mx.utils.LinkedList;
import mx.utils.LinkedListNode;

public class LinkedListIterator {
    protected var _list:LinkedList
    protected var _node:LinkedListNode;

    /**
     * Constructor.
     *
     * @param list The source LinkedList to provide a traversal API level on top of.
     * @param node Optional. The node pointer to start. If null, defaults to head.
     */
    public function LinkedListIterator( list:LinkedList, node:LinkedListNode = null )
    {
        _list = list;
        _node = node;
        if( !isValid() )
        {
            start();
        }
    }

    /**
     * @private
     *
     * Returns flag of current node pointer being non-null.
     * @return Boolean
     */
    protected function isValid():Boolean
    {
        return _node != null;
    }

    /**
     * Returns the current node value and moves node pointer forward in the list.
     * @return *
     */
    public function next():*
    {
        var data:*;
        if( isValid() )
        {
            data = _node.value;
            _node = _node.next;
        }
        return data;
    }

    /**
     * Returns the previous node value and moves node pointer backward in the list.
     * @return *
     */
    public function previous():*
    {
        var data:*;
        if( isValid() )
        {
            data = _node.value;
            _node = _node.prev;
        }
        return data;
    }

    /**
     * Returns flag of current node having a pointer to the next node in the list.
     * @return Boolean
     */
    public function hasNext():Boolean
    {
        return _node.next != null;
    }

    /**
     * Returns flag of current node having pointer to the previous node in the list.
     * @return Boolean
     */
    public function hasPrevious():Boolean
    {
        return _node.prev != null;
    }

    /**
     * Sets the node pointer to the head of the list source.
     */
    public function start():void
    {
        _node = _list.head;
    }

    /**
     * Sets the node pointer to the tail of the list source.
     */
    public function end():void
    {
        _node = _list.tail;
    }

    /**
     * Returns the data at the current node.
     * @return *
     */
    public function get data():*
    {
        return (_node) ? _node.value : null;
    }

    /**
     * Removes any held references to free up for GC.
     */
    public function dispose():void
    {
        _list = null;
        _node = null;
    }
}
}
